package lock.sales;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @AUTHOR LYF
 * @DATE 2022/3/19
 * @VERSION 1.0
 * @DESC
 */

// 1.创建资源类
class SaleTicket{
    private int number=1000;
    void sale(){
        while(number>0)
             System.out.println(Thread.currentThread().getName()+"卖出一张票,剩余"+ --number);
    }
}
// 加synchronized --- 会串行化的卖出---注意加锁的位置
class SaleTicket2{
    private volatile int number=1000;
    synchronized void sale(){
        while(number>0)
            System.out.println(Thread.currentThread().getName()+"卖出一张票,剩余"+ --number);
    }
}
class SaleTicket3{
    private volatile int number=1000;
     void sale(){
        while(number>0) {
            synchronized (this) {
                if(number>0) // 双重判断--单例---中的双重锁
                   System.out.println(Thread.currentThread().getName() + "卖出一张票,剩余" + --number);
            }
        }
    }
}
class SaleTicket4{
    private volatile int number=1000;
    // 卖奇数 ---注意要加上 synchronized否则报错----current thread is not owner
   synchronized void saleOod() throws InterruptedException {
        while(number>0) {
//            synchronized (this) {
//                if(number>0) // 双重判断--单例---中的双重锁
//                    System.out.println(Thread.currentThread().getName() + "卖出一张票,剩余" + --number);
//            }
            while(number%2!=1)
                this.wait();//等待--P操作，当满足何种条件时，则等待--

            System.out.println(Thread.currentThread().getName() + "在奇数时卖出一张票,剩余" + --number);

            this.notifyAll();// 通知其他人
        }
    }

    // 卖偶数
   synchronized void saleEven() throws InterruptedException {
        while(number>0) {
//            synchronized (this) {
//                if(number>0) // 双重判断--单例---中的双重锁
//                    System.out.println(Thread.currentThread().getName() + "卖出一张票,剩余" + --number);
//            }
            while(number%2==1)
                this.wait();//等待--P操作，当满足何种条件时，则等待--

            System.out.println(Thread.currentThread().getName() + "在偶数时卖出一张票,剩余" + --number);

            this.notifyAll();// 通知其他人

        }
    }
}

class SaleTicket5{
    private volatile int number = 100;
    ReentrantLock reentrantLock = new ReentrantLock();
    Condition condition = reentrantLock.newCondition();
    void saleOod() throws InterruptedException {
        while(number>0){
            reentrantLock.lock();

            while(number%2!=1)
                condition.await();

            if(number>0)
                System.out.println(Thread.currentThread().getName()+"进行卖票--剩余"+ --number);


            condition.signalAll();//先通知
            reentrantLock.unlock();//最后释放锁

        }

    }

    void saleEven() throws InterruptedException {
       while(number>0){
           reentrantLock.lock();

           while(number%2==1)
               condition.await();

           if(number>0)
               System.out.println(Thread.currentThread().getName()+"进行卖票--剩余"+ --number);


           condition.signalAll();
           reentrantLock.unlock();
       }

    }

}


public class SaleDemo {
    public static void main(String[] args) {
        // 2.进行多用户的卖票
        // 不加锁的情况
        SaleTicket5 saleTicket = new SaleTicket5();// 创建一个资源

        for (int i = 0; i < 2; i++) {
            new Thread(()->{
                Integer no = Integer.valueOf(Thread.currentThread().getName().substring(7));

                try {
                    if(no%2==1)
                        saleTicket.saleOod();
                    else
                        saleTicket.saleEven();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },"Thread-"+i).start();
        }
    }
}
